package cn.edu.njtc.controller;

import cn.edu.njtc.common.R;
import cn.edu.njtc.entity.dto.*;
import cn.edu.njtc.entity.pojo.Doctor;
import cn.edu.njtc.entity.pojo.DoctorDetail;
import cn.edu.njtc.entity.pojo.Hospital;
import cn.edu.njtc.entity.vo.DoctorVO;
import cn.edu.njtc.exception.BizException;
import cn.edu.njtc.service.DoctorService;
import cn.edu.njtc.service.DoctorDetailService; // 新增这一行，导入 DoctorDetailService
import cn.edu.njtc.service.HospitalService; // 引入 HospitalService
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; // 用于DTO参数校验
import org.springframework.beans.BeanUtils; // 用于对象属性拷贝
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Tag(name = "医生管理接口")
@RestController
@RequestMapping("/doctor")
public class DoctorController {

    @Autowired
    private DoctorService doctorService;

    @Autowired
    private HospitalService hospitalService;

    @Autowired
    private DoctorDetailService doctorDetailService;

    @Operation(summary = "新增医生及详细信息")
    @PostMapping("/add")
    public R<String> addDoctor(@RequestBody @Valid DoctorAddDTO doctorAddDTO) {
        // 检查手机号是否已注册
        LambdaQueryWrapper<Doctor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Doctor::getPhone, doctorAddDTO.getPhone())
                .eq(Doctor::getDeleted, false);
        if (doctorService.count(queryWrapper) > 0) {
            return R.failed("手机号已注册");
        }

        // 检查医院是否存在
        Hospital hospital = hospitalService.getById(doctorAddDTO.getHospitalId());
        if (hospital == null || hospital.getDeleted()) {
            return R.failed("指定的医院不存在或已删除");
        }

        // DTO转POJO
        Doctor doctor = new Doctor();
        BeanUtils.copyProperties(doctorAddDTO, doctor); // 拷贝相同属性
        doctor.setCreated(LocalDateTime.now());
        doctor.setDeleted(false);

        DoctorDetail doctorDetail = new DoctorDetail();
        doctorDetail.setDoctorIntroduction(doctorAddDTO.getDoctorIntroduction());
        doctorDetail.setExperienceYears(doctorAddDTO.getExperienceYears());
        doctorDetail.setSpecialties(doctorAddDTO.getSpecialties());
        doctorDetail.setCreated(LocalDateTime.now());
        doctorDetail.setDeleted(false);

        // 调用Service层方法，通过事务保存医生和详细信息
        boolean success = doctorService.saveDoctorAndDetail(doctor, doctorDetail);
        if (success) {
            return R.ok("医生新增成功");
        }
        return R.failed("医生新增失败");
    }

    @Operation(summary = "更新医生及详细信息")
    @PutMapping("/update")
    public R<String> updateDoctor(@RequestBody @Valid DoctorUpdateDTO doctorUpdateDTO) {
        // 检查医生是否存在
        Doctor existingDoctor = doctorService.getById(doctorUpdateDTO.getId());
        if (existingDoctor == null || existingDoctor.getDeleted()) {
            return R.failed("医生不存在或已删除");
        }

        // 如果手机号更新了，检查新手机号是否被其他医生占用
        if (StringUtils.hasText(doctorUpdateDTO.getPhone()) &&
                !doctorUpdateDTO.getPhone().equals(existingDoctor.getPhone())) {
            LambdaQueryWrapper<Doctor> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Doctor::getPhone, doctorUpdateDTO.getPhone())
                    .eq(Doctor::getDeleted, false)
                    .ne(Doctor::getId, doctorUpdateDTO.getId());
            if (doctorService.count(queryWrapper) > 0) {
                return R.failed("更新失败：手机号已被其他医生使用");
            }
        }

        // 如果更新了医院ID，检查新医院是否存在
        if (doctorUpdateDTO.getHospitalId() != null && !doctorUpdateDTO.getHospitalId().equals(existingDoctor.getHospitalId())) {
            Hospital hospital = hospitalService.getById(doctorUpdateDTO.getHospitalId());
            if (hospital == null || hospital.getDeleted()) {
                return R.failed("指定的医院不存在或已删除");
            }
        }

        // DTO转POJO，只拷贝非空属性以实现部分更新
        Doctor doctor = new Doctor();
        BeanUtils.copyProperties(doctorUpdateDTO, doctor); // 只拷贝id，其他通过setIndividualFieldsFromDto更新
        doctor.setUpdated(LocalDateTime.now());

        DoctorDetail doctorDetail = new DoctorDetail();
        doctorDetail.setDoctorId(doctorUpdateDTO.getId()); // 详细信息的ID与医生ID一致
        doctorDetail.setDoctorIntroduction(doctorUpdateDTO.getDoctorIntroduction());
        doctorDetail.setExperienceYears(doctorUpdateDTO.getExperienceYears());
        doctorDetail.setSpecialties(doctorUpdateDTO.getSpecialties());
        doctorDetail.setUpdated(LocalDateTime.now());

        boolean success = doctorService.updateDoctorAndDetail(doctor, doctorDetail);
        if (success) {
            return R.ok("医生信息更新成功");
        }
        return R.failed("医生信息更新失败");
    }

    @Operation(summary = "根据ID查询医生详情（含详细信息）")
    @GetMapping("/{id}")
    public R<DoctorVO> getDoctorById(@Parameter(description = "医生ID") @PathVariable Integer id) {
        Doctor doctor = doctorService.getById(id);
        if (doctor == null || doctor.getDeleted()) {
            return R.failed("未找到对应医生或已删除");
        }
        DoctorDetail doctorDetail = null;
        if (doctor.getId() != null) {
            doctorDetail = doctorDetailService.getById(doctor.getId()); // DoctorDetail 的主键就是 doctorId
        }

        // 构造 DoctorVO
        DoctorVO doctorVO = new DoctorVO();
        BeanUtils.copyProperties(doctor, doctorVO); // 拷贝 Doctor 基本信息

        if (doctorDetail != null && !doctorDetail.getDeleted()) {
            // 拷贝 DoctorDetail 的相关信息到 DoctorVO
            doctorVO.setDoctorIntroduction(doctorDetail.getDoctorIntroduction());
            doctorVO.setExperienceYears(doctorDetail.getExperienceYears());
            doctorVO.setSpecialties(doctorDetail.getSpecialties());
        }

        // 填充医院名称
        if (doctor.getHospitalId() != null) {
            Hospital hospital = hospitalService.getById(doctor.getHospitalId());
            if (hospital != null && !hospital.getDeleted()) {
                doctorVO.setHospitalName(hospital.getHospitalName());
            }
        }

        return R.ok(doctorVO);
    }

    @Operation(summary = "分页查询医生列表")
    @GetMapping("/page")
    public R<Page<DoctorVO>> getDoctorPage(
            @Parameter(description = "页码，从1开始", example = "1") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") Integer pageSize,
            @Parameter(description = "医生姓名或手机号关键词 (可选)", example = "张医生") @RequestParam(required = false) String keyword) {

        Page<Doctor> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Doctor> queryWrapper = new LambdaQueryWrapper<>();

        if (StringUtils.hasText(keyword)) {
            // 根据姓名或手机号模糊查询
            queryWrapper.and(wrapper -> wrapper
                    .like(Doctor::getName, keyword)
                    .or()
                    .like(Doctor::getPhone, keyword)
            );
        }
        queryWrapper.eq(Doctor::getDeleted, false); // 仅查询未被逻辑删除的医生
        queryWrapper.orderByDesc(Doctor::getCreated); // 按创建时间倒序

        Page<Doctor> doctorPage = doctorService.page(page, queryWrapper);

        // 将 Doctor Page 转换为 DoctorVO Page
        Page<DoctorVO> doctorVOPage = new Page<>(pageNum, pageSize, doctorPage.getTotal());
        List<DoctorVO> doctorVOList = doctorPage.getRecords().stream()
                .map(doctor -> {
                    DoctorVO vo = new DoctorVO();
                    BeanUtils.copyProperties(doctor, vo);

                    // 填充医院名称
                    if (doctor.getHospitalId() != null) {
                        Hospital hospital = hospitalService.getById(doctor.getHospitalId());
                        if (hospital != null && !hospital.getDeleted()) {
                            vo.setHospitalName(hospital.getHospitalName());
                        }
                    }
                    return vo;
                })
                .collect(Collectors.toList());
        doctorVOPage.setRecords(doctorVOList);

        return R.ok(doctorVOPage);
    }

    @Operation(summary = "逻辑删除医生")
    @DeleteMapping("/delete/{id}")
    public R<String> deleteDoctor(@Parameter(description = "医生ID") @PathVariable Integer id) {
        Doctor doctor = doctorService.getById(id);
        if (doctor == null || doctor.getDeleted()) {
            return R.failed("医生不存在或已删除");
        }
        // 调用Service层封装的逻辑删除方法
        boolean success = doctorService.deleteDoctorAndDetail(id);
        if (success) {
            return R.ok("医生删除成功");
        }
        return R.failed("医生删除失败");
    }

    @Operation(summary = "批量逻辑删除医生")
    @DeleteMapping("/batchDelete")
    public R<String> batchDeleteDoctors(@Parameter(description = "医生ID列表") @RequestBody List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            return R.failed("删除ID列表不能为空");
        }
        // 循环调用逻辑删除方法，或者在Service层封装一个批量逻辑删除
        boolean allSuccess = true;
        for (Integer id : ids) {
            boolean success = doctorService.deleteDoctorAndDetail(id);
            if (!success) {
                allSuccess = false;
                // 实际项目中可以记录下失败的ID并返回
                // return R.failed("部分医生删除失败，ID：" + id);
            }
        }
        if (allSuccess) {
            return R.ok("批量删除医生成功");
        }
        return R.failed("批量删除医生失败"); // 简单处理为只要有失败就返回失败
    }

    @Operation(summary = "医生登录", description = "用户名密码登录")
    @PostMapping("/login")
    public R<DoctorTokenDto> login(@RequestBody DoctorLoginDto doctorLoginDto) throws BizException {
        DoctorTokenDto doctorTokenDto = doctorService.login(doctorLoginDto);
        return R.ok(doctorTokenDto);
    }




        @Operation(summary = "医生注册", description = "手机号注册")
        @PostMapping("/register")
        public R<Integer> register(@RequestBody DoctorRegisterDto doctorRegisterDto) throws BizException {
            int register = doctorService.register(doctorRegisterDto);
            return R.ok(register);
        }
}